# %%
from strategy_mode import dataLoader, str_cal, Trading, TradingRules, TradingLoop
from strategy_mode import TradingStrategy_sum_02 as Strgs
from DataShow import Strategy_Plot_5 as plot
from DataTools import datatool
from OtherTools import filetool
import math
import pandas as pd
import gc
import os
import re


def LoadingLoop(
    code,
    StockDataDic,
    pre="5",
    printLens=60,
    endday="2018-11-10",
    Cutting_start_date="2018-11-10",
    dirDic={
        "Main": "D:/StockDatas/",
        "basic": "basic/",
        "daily": "163_Daily_Bar/",
        "report": "Reports/",
        "temp": "temp/",
        "ticker": "History_ticker/",
        "mins": "History_mins/",
    },
):

    stock_details = StockDataDic[code]
    df = dataLoader.LoadDF(
        code,
        stock_details,
        pre=pre,
        startdate=Cutting_start_date,
        endday=endday,
        dirDic=dirDic,
        printLens=printLens,
    )
    print("loaded".center(printLens, " "))
    gc.collect()

    report_A, report_Q = dataLoader.ReportConvent(
        code,
        stock_details,
        endday=endday,
        dirDic=dirDic,
        printLens=60,
    )  # 主要加载分装
    print("reported".center(printLens, " "))
    return stock_details, df, report_A, report_Q


def MainCalinLoop(
    df,
    Ma_Day_List=[3, 5, 8],
    pre=48,
    distionSearchDay=10,
    MainLines_CountStartGroup=1,
    line_Pares=2,
    printLens=60,
    keyls=["low", "open", "close", "high"],
):
    df = str_cal.MAsBuliderMAIN(df, keyls, Ma_Day_List, shift=False)  # 计算各种MA，MA布尔值等等
    df = str_cal.Macount(df, Ma_Day_List)
    df = str_cal.Ma_order_count(df, Ma_Day_List, keyls)
    print("ma_done".center(printLens, " "))
    df = str_cal.SellSignal(
        df, Ma_Day_List, startday=MainLines_CountStartGroup, line_Pares=line_Pares
    )  # 计算卖出信号，红蓝占比
    print("main_done".center(printLens, " "))
    gc.collect()
    # df = str_cal.BollFastSum(
    #     df, keyls, "_by%", Ma_Day_List=Ma_Day_List, sub_Key="", drop=False
    # )
    df = str_cal.BollFastSum_All(
        df, keyls, "_by%", Ma_Day_List=Ma_Day_List, sub_Key="", drop=False
    )

    """
    60分钟 5/3 std* 0.9 fillin = 32
    5分钟 48/? std * 0.9 filling = 96
    """
    df = df.fillna(0)
    pre_g = re.findall("\d*", pre)
    if pre_g != ["", ""]:
        gap = int(240 / int(pre))
    else:
        if "D" in pre.upper():
            gap = 8
        if "M" in pre.upper() or "Y" in pre.upper():
            gap = 1

    high = int(gap)
    low = int(gap * 0.2)
    cat = "All_by%_sum_{}_rolling"
    df.loc[:, cat.format(low)] = df["All_by%_sum"].rolling(low).mean()
    df.loc[:, "TH_" + cat.format(high)] = (
        df["All_by%_sum"].rolling(high).max().rolling(low).mean()
    )
    df.loc[:, "TL_" + cat.format(high)] = (
        df["All_by%_sum"].rolling(high).min().rolling(low).mean()
    )

    gc.collect()
    print("Boll_done".center(printLens, " "))

    df = Trading.distion(df, range_day=distionSearchDay)
    gc.collect()

    return df


def Strategy_Main(
    Strgs,
    pre="5",
    simulation_type="run",
    strname="str_1",
    codel=[
        "300999",
    ],
    DrawMode="close",
    distionSearchDay=[10],
    AvableCash=100000,
    tradePersentDic={"x1": 1},
    fees_Persent=0.0035,
    Cutting_start_date="2018-11-10",
    GroupOfLines=3,
    MainLines_CountStartGroup=1,
    printLens=60,
    keyls=["close", "low", "high", "open"],
    dirDic={
        "Main": "D:/StockDatas/",
        "basic": "basic/",
        "daily": "163_Daily_Bar/",
        "report": "Reports/",
        "temp": "temp/",
        "ticker": "History_ticker/",
        "mins": "History_mins/",
    },
):

    DirPath = dirDic["Main"] + dirDic["daily"]
    tempath = dirDic["Main"] + dirDic["temp"]
    filetool.DirPathChick(DirPath)
    filetool.DirPathChick(tempath)

    # 获取交易日信息
    endday = datatool.getTradedayinfo(
        MainPath=dirDic["Main"], subPath=dirDic["basic"], mode="LastOpenDay"
    )
    # print(endday)
    # 获取个股信息
    StockDataDic = datatool.getCodeAndDetail(
        MainPath=dirDic["Main"], subPath=dirDic["basic"]
    )

    res_L = []
    Ma_Day_List = str_cal.Waves(GroupOfLines - 1)
    line_Pares = len(Ma_Day_List) / (GroupOfLines)
    count_in = GroupOfLines - MainLines_CountStartGroup
    print(count_in, line_Pares)
    # GroupOfLines 输入到这里，5代表5组波浪线 [13, 21, 55, 89, 233, 377]

    Ma_Day_List.sort()

    print(str(Ma_Day_List).center(printLens, " "))
    _df = pd.DataFrame()

    for code in codel:
        avableCash = AvableCash
        print(code.center(printLens, "-"))
        stock_details, df, report_A, report_Q = LoadingLoop(
            code,
            StockDataDic,
            endday=endday,
            pre=pre,
            printLens=60,
            dirDic=dirDic,
            Cutting_start_date=Cutting_start_date,
        )
        print(
            "{} >> {}".format(df.iloc[0].date, df.iloc[-1].date).center(printLens, " ")
        )

        df = MainCalinLoop(
            df,
            Ma_Day_List,
            pre=pre,
            distionSearchDay=distionSearchDay,
            MainLines_CountStartGroup=1,
            line_Pares=line_Pares,
            keyls=keyls,
            printLens=60,
        )
        trading_Log = TradingLoop.TradingMainLoop(
            df,
            Ma_Day_List,
            Strgs,
            count_in=count_in,
            line_Pares=line_Pares,
            simulation_type=simulation_type,
            tradePersentDic=tradePersentDic,
            AvableCash=avableCash,
            Value_Pread_Mode="M",
            # tag_day=distionSearchDay,
        )
        # trading_Log.to_csv("log_trading.csv")

        df = pd.merge(df, trading_Log, on="date")
        dic = str_cal.resoult(df, code, avableCash)

        res_L.append(dic)
        # 输出层
        for key in dic:
            print("--- {}:{} ---".format(key, dic[key]).center(printLens, " "))
        print("- Draw -".center(printLens, " "))
        title = "{} 年化:{}% 期内: {}% {} {}".format(
            code,
            str(round(dic["%_pre_year"] * 100, 2)),
            str(round(dic["%_increase"] * 100, 2)),
            strname,
            distionSearchDay,
        )

        plot.DRAW(
            df,
            report_A,
            report_Q,
            Ma_Day_List=Ma_Day_List,
            title=title,
            mode=DrawMode,
        )
        _df = pd.concat([_df, df])
        _df.to_csv("logs_{}.csv".format(strname), index=False)
        pd.DataFrame(res_L).to_csv("res{}.csv".format(strname))
        print("{} {} output".format(code, "logs res").center(printLens, " "))
        gc.collect()

    print(" finish ".center(printLens, "*"))
    del df
    gc.collect()


#%%
if __name__ == "__main__":

    strname = "str_sum_01"
    simulation_type = "test"
    Cutting_start_date = "2020-06-01"
    pre = "15"
    GroupOfLines = 4
    distionSearchDay = 20
    pre_g = re.findall("\d*", pre)
    if pre_g != ["", ""]:
        distionSearchDay = int(distionSearchDay * 240 / int(pre_g[0]))
    import json

    path = "config.json"
    with open(path, mode="r") as f:
        res = f.read()
    dirDic = json.loads(res)["SavePath"]
    codel = [
        "300999",
        # "601398",
        # "600010",
        # "000001",
        # "688330",
        # "300894",
        "000008",
        # "600605",
        "600090",
        # "600652",
        # "600086",
        # "600145",
        # "600112",
        # "600083",
        # "600091",
        # "600654",
        # "600146",
        # "600122",
        # "600604",
        # "600601",
        # "000858",
        # "000568",
        # "000596",
        # "000009",
        # "600071",
        # "600080",
        # "000005",
        # "000007",
        # "600603",
        # "600608",
        # "600653",
        # "600084",
        # "002069",
        # "600119",
    ]
    # codel = set(codel)
    Strategy_Main(
        Strgs,
        pre=pre,
        strname=strname,
        simulation_type=simulation_type,
        codel=codel,
        DrawMode="close",
        distionSearchDay=distionSearchDay,
        AvableCash=100000,
        tradePersentDic={"x1": 1},
        fees_Persent=0.0035,
        Cutting_start_date=Cutting_start_date,
        GroupOfLines=GroupOfLines,
        MainLines_CountStartGroup=0,
        printLens=60,
        dirDic=dirDic,
    )
    import datetime

    now = int("".join(datetime.datetime.now().strftime("%H:%M:%S").split(":")))
    if 0 > now > 630:
        os.system("shutdown -s -t 30")
    exit()